/*
 *Copyright (c) 2008, Scendix Software, Inc.
 * 
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Win32;
using Microsoft.MediaCenter;
using Microsoft.MediaCenter.Hosting;
using Microsoft.MediaCenter.UI;
using System.Data.OleDb;
using System.Data;
using System.IO;
using mceTapiRexv2.Utils;
using SKYPE4COMLib;
using Redemption;
using TapiRex;

namespace mceTapiRexv2
{

    /// <summary>
    /// This is the global coordinating object for the application.
    /// It handles the general page navigation.
    /// </summary>
    /// 

    public class Application  : ModelItem
    {
        /// <summary>
        /// Empy constructor to enable markup creation for when we want
        /// to run in McmlPad standalone.
        /// </summary>
        ///     
        private Choice iPPChoice = new Choice();
        public string primarySource;
        public string ignoreOutlook;
         private TapiRex.Application tRexApplication;


        public Application()
            : this(null, null)
        {
        }
        private static Application singleApplicationInstance;

        private HistoryOrientedPageSession session;
        private AddInHost host;

        /// <summary>
        /// Construct an Application object and associate it with a page
        /// session.
        /// </summary>
        public Application(HistoryOrientedPageSession session, AddInHost host)
        {
            // Store the page session and host
                this.session = session;

                
                this.host = host;
           if(this.host!=null)
        
            // initialize the field used by the static Application.Current property
            singleApplicationInstance = this;
        }
        public TapiRex.Application TapiRexApplication
        {
            get
            {
                if (tRexApplication == null)
                {
                    TapiRex.Helper TRexHelper = new TapiRex.Helper();
                    TapiRex.Application app = TRexHelper.GetApplication;
                    tRexApplication = app;
                }
                return tRexApplication;
            }

        }

        public void GoToUrl(String url)
        {

            Application curr = Current;
            MediaCenterEnvironment mcEnvironment = curr.MediaCenterEnvironment;
            if (mcEnvironment != null)
                mcEnvironment.NavigateToPage(PageId.ExtensibilityUrl, url);
            else
                ToolsLib.LogStr("GoToUrl failed : "+ url);
        }
        /// <summary>
        /// The one and only instance of Application running in this process
        /// </summary>
        public static Application Current
        {
            get
            {
                return singleApplicationInstance;
            }
        }
        /// <summary>
        /// The Media Center environment.
        /// </summary>
        public MediaCenterEnvironment MediaCenterEnvironment
        {
            get
            {
                if (host == null)
                    return null;

                return host.MediaCenterEnvironment;
            }
        }

        /// <summary>
        /// Navigate to the main menu.
        /// </summary>
        public void GoToStartPage()
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
             properties["Application"] = this;
      
            if (session != null)
            {
                
                session.GoToPage("resx://mceTapiRexv2/mceTapiRexv2.Resources/Default");
            }
            else
            {
                Debug.WriteLine("GoToStartPage");
            }
        }
        /// <summary>
        /// reads primary source from registry, if not done yet
        /// </summary>
        public string lookupPrimarySource()
        {
            if(this.primarySource==null)
            {
                this.primarySource = RegistryUtil.ReadFromRegistry(Registry.LocalMachine, "SOFTWARE\\Scendix\\TapiRex\\Options", "DataSource", "0");
            }
            return this.primarySource;
        }        
        /// <summary>
        /// reads ignore outlook option from registry if not done yet
        /// </summary>
        public string lookupIgnoreOutlook()
        {
            if (this.ignoreOutlook == null)
            {
                this.ignoreOutlook = RegistryUtil.ReadFromRegistry(Registry.LocalMachine, "SOFTWARE\\Scendix\\TapiRex\\Options", "DisableOutlook", "0");
            }
            return this.ignoreOutlook;
        }
        /// <summary>
        /// checks if skype is running. if so consider skype information when looking for contact details
        /// </summary>
        /// <returns>1 if skype is running, 0 else</returns>
        public bool useSkype()
        {
            Process[] arrProcesses = Process.GetProcessesByName("Skype");
            if (arrProcesses.Length > 0 && false)
                return true;
            else
                return false;

        }
        /// <summary>
        /// checks if outlook is set as primary source  in TapiRex for the reverse lookup
        /// </summary>
        /// <returns></returns>
        public bool isOutlookPrimarySource()
        {
            return ((lookupPrimarySource() == "2") && (lookupIgnoreOutlook() != "1"));
        }
        /// <summary>
        /// checks if the database is set as primary source  in TapiRex for the reverse lookup
        /// </summary>
        /// <returns></returns>
        public bool isDatabasePrimarySource()
        {
            return (lookupPrimarySource() == "1");
        }


        /// <summary>
        /// Navigate to the specified  page.
        /// </summary>
        /// <param name="page">The state object for the  page</param>
        public void GoToPage(String page)
        {
            Application curr = Current;
            HistoryOrientedPageSession currSess = curr.session;
            // If we have no page session, just spit out a trace statement.
            if (currSess != null)
            {
                currSess.GoToPage("resx://mceTapiRexv2/mceTapiRexv2.Resources/" + page);
            }
            //
            // Construct the arguments dictionary and then navigate to the
            // details page template.
            //
        }
        //public Image getImageFromLibrary(string imgName)
        //{
        //    try
        //    {
        //        Application app = Current;
                
                
        //        McmlLoadResult res = app.host.LoadMcml("resx://mceTapiRexv2/" + imgName);
        //        Image img = res.GetImage(imgName);
        //    }
        //    catch
        //    {
        //        LogStr("Error loading image: " + imgName + " from resources");
        //        return null;
        //    }

        //}
        public void GoToPage(String page,string param, string uiProp, object obj)
        {
            Application curr = Current;
            HistoryOrientedPageSession currSess = curr.session;
            // If we have no page session, just spit out a trace statement.
            if (currSess != null)
            {
                IDictionary<string,object> uiProperties = new Dictionary<string,object>();
                uiProperties.Add(uiProp,obj);
                param = (param.Trim() != "") ? "#" + param : "";
                currSess.GoToPage("resx://mceTapiRexv2/mceTapiRexv2.Resources/" + page+param,uiProperties);
            }
        }

        /// <summary>
        /// Navigate back to the previous page.
        /// </summary>
        public void GoBack()
        {
            Application curr = Current;
            HistoryOrientedPageSession currSession = curr.session;
            if (currSession == null)
            {
                Debug.WriteLine("GoBack");
                return;
            }
            currSession.BackPage();
        }

        /// <summary>
        /// Get the location of the Z logo to use in a call to Dialog().
        /// </summary>
        private string DialogIconImagePath
        {
            get
            {
                //
                // NOTE: The Dialog() API requires a standard Uri, which means
                // we are limited to file:// or http://. We created a registry key
                // which is written with the MSI to look up where Z is installed,
                // and query for that value here.
                //

                string installLocation = Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Scendix\TapiRex", @"InstallDir", null) as string;
                if (installLocation == null)
                    installLocation = Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Scendix\TapiRex", @"InstallDir", null) as string;

                string imagePath = String.Format("file://{0}\\mceTapiRex.png", installLocation);
                return imagePath;
            }
        }

        /// <summary>
        /// Displays a simple "OK" message box
        /// </summary>
        public void MessageBox(string text, string caption)
        {
            MessageBox(text, caption, 5, true);
        }

        /// <summary>
        /// Displays a simple "OK" message box, branded with the Z logo.
        /// </summary>
        public void MessageBox(string text, string caption, int timeout, bool modal)
        {
            if (MediaCenterEnvironment == null)
            {
                Debug.WriteLine(String.Format("Dialog {0}: {1}", caption, text));
                return;
            }

            MediaCenterEnvironment.Dialog(
                text,
                caption,
                new object[] { DialogButtons.Ok },
                timeout,
                modal,
                DialogIconImagePath,
                delegate(DialogResult dialogResult) { });
        }
        public String   itemsPP
        {
            get
            {
                return getSetting("calls_per_page", "20");
            }
            set
            {
                Debug.WriteLine("Set items per page to" + value);
                setSetting("calls_per_page", value);
            }
        }

        public String currStyle
        {
            get
            {
                return getSetting("skin", "cbuenger");
            }
            set
            {
                setSetting("skin", value);
            }
        }

        public Choice itemsPPselect
        {
            get
            {
                Choice iPPChoice = new Choice();
                List<String> options = new List<string>();
                for( int i=1 ; i<=10 ;i++)
                {
                    String opt = (i*5).ToString();
                    options.Add(opt);
                }
                for (int k = 6; k <= 10; k++)
                {
                    String opt = (k * 10).ToString();
                    options.Add(opt);
                }
                options.Add("all");
                iPPChoice.Options = options;
                iPPChoice.Chosen = itemsPP;
                return iPPChoice;
            }
        }


        public Choice styleSelect
        {
            get
            {
                Choice styleChoice = new Choice();
                List<String> options = new List<string>();

                    String opt = "cbuenger";
                    options.Add(opt);
                    styleChoice.Options = options;
                    styleChoice.Chosen = currStyle;
                    return styleChoice;
            }
        }

        private String getSetting(String opt)
        {
            return getSetting(opt, "");
        }
        private String getSetting(String opt, string sdefault)
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Scendix\\TapiRex");
            String path = key.GetValue("InstallDir").ToString();
            if (path != null)
            {
                OleDbConnection con = new OleDbConnection(
                @"Provider=Microsoft.Jet.OLEDB.4.0;
                Data Source=" + path + "data.mdb");
               // DataSet ds = new DataSet();
                String query = "SELECT OptionsValue FROM Options WHERE OptionsName='" + opt + "'";
                con.Open();
                OleDbCommand cmd = new OleDbCommand(query, con);
                 OleDbDataReader dr = cmd.ExecuteReader();
                 dr.Read();
                 string sret = sdefault;
                if(dr.HasRows)
                    sret = dr.GetString(0);
                dr.Close();
                con.Close();
                return sret;
            }
            return sdefault;
        }

       public String getResString(String resId)
        {
            return getResString(resId, "", "");
        }
       public String getResString(String resId, String str1)
        {
            return getResString(resId, str1, "");
        }
        public String getResString(String resId, String str1, String str2)
        {
            int result;
            if (!int.TryParse(resId,out result))
                return resId;
            
            RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Scendix\\mceTapiRexv2");
            String path = key.GetValue("InstallDir").ToString();
            if (path != null)
            {
                OleDbConnection con = new OleDbConnection(
                @"Provider=Microsoft.Jet.OLEDB.4.0;
                    Data Source=" + path + "langdata.mdb");
                String lang = key.GetValue("LanguageColumn").ToString();
                String query = "SELECT "+lang+",Native FROM resstrings WHERE ID=" + resId;

                try
                {
                    con.Open();
                    OleDbCommand cmd = new OleDbCommand(query, con);
                    OleDbDataReader dr = cmd.ExecuteReader();
                    dr.Read();
                    string sret = "";
                    if (dr.HasRows)
                    {
                        if(dr.IsDBNull(0))
                            sret = dr.GetString(1);
                        else
                            sret = dr.GetString(0);
                        sret = sret.Replace("%s", str1);
                    }
                    else
                        sret = "?#" + resId;
                    dr.Close();
                    con.Close();
                    return sret;
                }
                catch (Exception ex)
                {
                    ToolsLib.LogStr("getResString(" + resId + "): " + ex.ToString());
                    return resId;
                }
            }
            return "";
        }
        public Image getPicture(string guid)
        {
            return getPicture(guid, guid);
        }
        public string getPicturePath(string guid, string id)
        {
            if (isOutlookPrimarySource())
            {
                Image temp = GetPictureFromOutlook(guid);
                if (temp != null)
                    return System.IO.Path.GetTempPath() + "\\" + guid + ".jpg";
            }
            else
            {
                connectDB db = new connectDB();
                String query = "SELECT Picture FROM Contacts WHERE ContactGUID='" + guid + "' AND NOT Picture IS NULL";
                DataSet ds = db.SelectQuery(query);
                DataTable dt = ds.Tables[0];
                if (dt.Rows.Count > 0)
                    return System.IO.Path.GetTempPath() + "\\" + guid + ".BMP";
            }
            if (useSkype() && (guid == "" || guid == id))
            {
                return GetPictureFromSkype(id);
            }
            return null;
        }


        public Image getPicture(string guid, string id)
        {
            //ToolsLib.LogStr("getPicture: " + guid);
            if (isOutlookPrimarySource())
            {
                Image temp = GetPictureFromOutlook(guid);
                if(temp!=null)
                    return temp;
            }
            else
            {
                connectDB db = new connectDB();
                String query = "SELECT Picture FROM Contacts WHERE ContactGUID='" + guid + "' AND NOT Picture IS NULL";
                DataSet ds =  db.SelectQuery(query);
                DataTable dt = ds.Tables[0];
                if (dt.Rows.Count >0)
                {
                    DataRow dr = dt.Rows[0];
                    byte[] MyData = new byte[0];
                    MyData = (byte[])dr["Picture"] ;
                    int ArraySize = new int();
                    ArraySize = MyData.GetUpperBound(0);
                    String Filepath = System.IO.Path.GetTempPath() + "\\" + guid + ".BMP";
                    FileStream fs = new FileStream(Filepath, FileMode.OpenOrCreate, FileAccess.Write);

                    fs.Write(MyData, 0, ArraySize);
                    fs.Close();
                    Image ttemp = new Microsoft.MediaCenter.UI.Image("file://" + Filepath);
                    if(ttemp!=null)
                        return ttemp;
                }

               
            }
            if (useSkype() && (guid == "" || guid == id))
            {
                String sSkypeImage = GetPictureFromSkype(id);
                if (sSkypeImage != "")
                    return new Microsoft.MediaCenter.UI.Image("file://" + sSkypeImage);
            }
            return null;
        }
        public RDOContactItem getOutlookContact(string guid)
        {
            if (guid == null || guid == "" || guid.Contains("{"))
                return null;

            try
            {
                RDOSession session = new RDOSession();
                session.Logon("", "", false, false, false, false);
                RDOFolder folder = session.GetDefaultFolder(rdoDefaultFolders.olFolderContacts);
                RDOItems item = folder.Items.Restrict("SELECT * FROM Folder WHERE " +
                    " MessageClass='IPM.Contact' AND EntryID='" + guid + "'");
                if (item.Count > 0)
                {
                    RDOContactItem cont = (RDOContactItem)item.Item(1);
                    return cont;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message.ToString());
                ToolsLib.LogStr(e.Message.ToString());
            }
            return null;
       }
        public Contact getContactFromOutlook(string guid, Image picture)
        {
            try
            {
                RDOContactItem oContact = getOutlookContact(guid);
                return new Contact(oContact, picture);
            }
            catch
            {

                return null;
            }
        }
        public Contact getContactFromOutlook(string guid)
        {
            try
            {
                RDOContactItem oContact = getOutlookContact(guid);
                return new Contact(oContact,GetPictureFromOutlook(guid));
            }
            catch
            {

                return null;
            }
        }
        public Image BufferOutlookPicture(String entryId)
        {
            return GetPictureFromOutlook(entryId);
        }
        public Image BufferOutlookPicture(RDOContactItem oContact)
        {
            string sTempFile = System.IO.Path.GetTempPath() + "\\" + oContact.EntryID + ".jpg";
            return BufferOutlookPicture(oContact, sTempFile);
        }
     
        public Image BufferOutlookPicture(RDOContactItem oContact, string sTempFile)
        {
            if (oContact.HasPicture)
            {
                //"ContactPicture.jpg"
                for (int i = 1; i <= oContact.Attachments.Count; i++)
                {
                    if (oContact.Attachments.Item(i).FileName == "ContactPicture.jpg")
                    {
                        if (File.Exists(oContact.Attachments.Item(i).PathName))
                            return new Microsoft.MediaCenter.UI.Image("file://" + oContact.Attachments.Item(i).PathName);
                        oContact.Attachments[i].SaveAsFile(sTempFile);
                        return new Microsoft.MediaCenter.UI.Image("file://" + sTempFile);
                    }
                }
            }
            return null;
        }
        public string GetPictureFromSkype(string sUserHandle)
        {

            try
            {
                ToolsLib.LogStr("GetPictureFromSkype: " + sUserHandle);
                if (sUserHandle.IndexOf(", ") > -1)

                    sUserHandle = sUserHandle.Substring(0, sUserHandle.IndexOf(", "));


                if (sUserHandle.StartsWith("undisclosed_pstn:"))

                    return "";

                string imagesDir = System.IO.Path.GetTempPath() + "userimages\\";

                if (!Directory.Exists(imagesDir))
                    Directory.CreateDirectory(imagesDir);

                string sTempUserFile = imagesDir + sUserHandle + ".jpg";

                if (File.Exists(sTempUserFile))
                    return sTempUserFile;


                SKYPE4COMLib.Command cmd = new SKYPE4COMLib.Command();

                cmd.Command = "GET USER " + sUserHandle + " AVATAR 1 " + sTempUserFile;

                Skype mobjSkype = new Skype();
                mobjSkype.SendCommand(cmd);



                int i = 0;

                while (!File.Exists(sTempUserFile) && i < 10)
                {

                    System.Threading.Thread.Sleep(200);

                    i++;

                }
                FileInfo fi = new FileInfo(sTempUserFile);

                if (fi.Length == 0)
                {

                    if (File.Exists(sTempUserFile))

                        File.Delete(sTempUserFile);

                    return "";

                }

                return sTempUserFile;
            }
            catch(Exception exception){
                Debug.WriteLine(exception);
                return  "";
            }


        }
        public Contact getContactFromDatabase(string guid, Image picture)
        {
            connectDB db = new mceTapiRexv2.Utils.connectDB();
            String query = "SELECT * FROM Contacts WHERE ContactGUID='" + guid + "' ";
            DataSet ds = db.SelectQuery(query);
            DataTable dt = ds.Tables[0];
            if (dt.Rows.Count >0)
            {
                Contact contact = new Contact(dt.Rows[1],picture);
                return contact;
            }
            return null;

        }
        public Contact getContactFromDatabase(string guid)
        {
            connectDB db = new mceTapiRexv2.Utils.connectDB();
            String query = "SELECT * FROM Contacts WHERE ContactGUID='" + guid + "' ";
           DataSet ds = db.SelectQuery(query);
            DataTable dt = ds.Tables[0];
            if (dt.Rows.Count >0)
            {
                Contact contact = new Contact(dt.Rows[1]);
                return contact;
            }
            return null;

        }
        private Image GetPictureFromOutlook(string guid)
        {
            String sTempFile = System.IO.Path.GetTempPath() + "\\"+guid+".jpg";
            if (File.Exists(sTempFile))
                return new Microsoft.MediaCenter.UI.Image("file://" + sTempFile);
            try{
            RDOContactItem oContact = getOutlookContact(guid);
                if(oContact != null)
                      return BufferOutlookPicture(oContact, sTempFile);
            }
            catch
            {
                //ToolsLib.LogStr(ex.ToString());
            }
            return null;
        }
        public Contact getContactFromSkype(string sUserHandle)
        {
            SKYPE4COMLib.User user = getSkypeUser(sUserHandle);
            return new Contact(user) ;
        }
        public SKYPE4COMLib.User getSkypeUser(string sUserHandle)
        {
            try
            {
                if (sUserHandle.IndexOf(", ") > -1)

                    sUserHandle = sUserHandle.Substring(0, sUserHandle.IndexOf(", "));

                if (sUserHandle.StartsWith("undisclosed_pstn:"))

                    return null;


                SKYPE4COMLib.Command cmd = new SKYPE4COMLib.Command();

                cmd.Command = "GET USER " + sUserHandle;

                Skype mobjSkype = new Skype();

                SKYPE4COMLib.User user = mobjSkype.get_User(sUserHandle);
                return user ;
            }
            catch{
                return null;
            }
        }

        private void setSetting(String opt, String val)
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Scendix\\TapiRex");
            String path = key.GetValue("InstallDir").ToString();
            Debug.WriteLine("setSetting: option = " + opt + " value : " + val);
            if (path != null && opt != "" && val != "")
            {
                OleDbConnection con = new OleDbConnection(
                @"Provider=Microsoft.Jet.OLEDB.4.0;
                    Data Source=" + path + "data.mdb");
                String query = "UPDATE Options SET OptionsValue=\"" + val + "\" WHERE OptionsName=\"" + opt + "\"";
                con.Open();
                OleDbCommand cmd = new OleDbCommand(query, con);
                int returnValue = cmd.ExecuteNonQuery();
                if(returnValue==0)
                {
                    query = "INSERT into Options values (\""+opt+"\" , \""+ val + "\")";
                    cmd = new OleDbCommand(query,con);
                    returnValue = cmd.ExecuteNonQuery();
                }
                con.Close();
            }
            else
            {
                Debug.WriteLine("Could not update setting");
            }
        }
        public void showMessageBox(string title, string message)
        {
             showMessageBox(title, message, Microsoft.MediaCenter.DialogButtons.Ok);
        }
        public void showMessageBox(string title, string message,object buttons)
        {
            
            AddInHost.Current.MediaCenterEnvironment.Dialog(message, title,(DialogButtons) buttons, 40, true);
        }
        public CallMember getCaller(int id)
        {
            string strSQL = "SELECT  CallDate,CallEnd,CallerID,CallerName,CalledName,Incoming,Answered, " +
            "New,CalledID,CallerGUID,CalledGUID FROM Calls WHERE CallID=" + id.ToString();
                mceTapiRexv2.Utils.connectDB db = new mceTapiRexv2.Utils.connectDB();
                DataSet ds = db.SelectQuery(strSQL);
                DataTable dt = ds.Tables[0];
                if (dt != null && dt.Rows.Count > 0)
                {
                    DataRow dr = dt.Rows[0];
                    return new CallMember(dr[3].ToString(), dr[2].ToString(), dr[9].ToString(), true);
                }
                else return null;

        }
        public Phonecall getPhonecall(int id)
        {
            string strSQL = "SELECT  CallDate,CallEnd,CallerID,CallerName,CalledName,Incoming,Answered, " +
            "New,CalledID,CallerGUID,CalledGUID FROM Calls WHERE CallID=" + id.ToString();
            mceTapiRexv2.Utils.connectDB db = new mceTapiRexv2.Utils.connectDB();
            DataSet ds = db.SelectQuery(strSQL);
            DataTable dt = ds.Tables[0];
            if (dt != null && dt.Rows.Count > 0)
            {
                DataRow dr = dt.Rows[0];
                return new Phonecall(dr);
            }
            else return null;

        }

    }
}
